              package com.java.diagnostics.visualizer.impl.data;
              
              import com.java.diagnostics.visualizer.data.AggregateData;
              import com.java.diagnostics.visualizer.data.Data;
              import com.java.diagnostics.visualizer.data.DomainData;
              import com.java.diagnostics.visualizer.data.StructuredData;
              import com.java.diagnostics.visualizer.data.TupleData;
              import com.java.diagnostics.visualizer.data.UnstructuredData;
              import com.java.diagnostics.visualizer.data.axes.Axis;
              import com.java.diagnostics.visualizer.data.axes.XDataAxis;
              import com.java.diagnostics.visualizer.data.axes.YDataAxis;
              import com.java.diagnostics.visualizer.data.ids.ID;
              import com.java.diagnostics.visualizer.impl.data.ids.AggregateIDImpl;
              import com.java.diagnostics.visualizer.properties.OutputProperties;
              import java.util.Collection;
              import java.util.Iterator;
              import java.util.Map;
              import java.util.TreeMap;
              
              public class AggregateDataImpl extends DataImpl
                implements AggregateData
              {
                private Map<ID, UnstructuredData> unstructuredData;
                private Map<ID, UnstructuredData> postprocessedUnstructuredData;
                private Map<ID, StructuredData> structuredData;
                private Map<ID, StructuredData> postprocessedStructuredData;
                private Map<ID, TupleData> tupleData;
                private Map<ID, TupleData> postprocessedTupleData;
                protected boolean postprocessing = false;
              
                private static final UnstructuredData[] unstructuredDataTemplateArray = new UnstructuredData[0];
              
                private static final StructuredData[] structuredDataTemplateArray = new StructuredData[0];
              
                private static final TupleData[] tupleDataTemplateArray = new TupleData[0];
                protected boolean dataIsDirty;
              
                public AggregateDataImpl()
                {
                  this("");
                }
              
                public AggregateDataImpl(String label) {
                  super(label);
                  this.unstructuredData = new TreeMap();
                  this.structuredData = new TreeMap();
                  this.tupleData = new TreeMap();
                  this.postprocessedUnstructuredData = new TreeMap();
                  this.postprocessedStructuredData = new TreeMap();
                  this.postprocessedTupleData = new TreeMap();
                }
              
                public boolean isEmpty() {
                  boolean parsedDataIsEmpty = (this.unstructuredData.size() == 0) && 
                    (this.structuredData.size() == 0) && (this.tupleData.size() == 0);
                  boolean postprocessedDataIsEmpty = (this.postprocessedUnstructuredData.size() == 0) && 
                    (this.postprocessedStructuredData.size() == 0) && 
                    (this.postprocessedTupleData.size() == 0);
                  return (parsedDataIsEmpty) && (postprocessedDataIsEmpty);
                }
              
                public UnstructuredData[] getUnstructuredData()
                {
                  Map merged = new TreeMap();
                  merged.putAll(this.unstructuredData);
                  merged.putAll(this.postprocessedUnstructuredData);
                  return (UnstructuredData[])merged.values().toArray(
                    unstructuredDataTemplateArray);
                }
              
                public UnstructuredData getUnstructuredData(String label)
                {
                  UnstructuredData unstructured = (UnstructuredData)searchForLabel(
                    this.unstructuredData, label);
              
                  if (unstructured == null) {
                    unstructured = (UnstructuredData)searchForLabel(
                      this.postprocessedUnstructuredData, label);
                  }
                  return unstructured;
                }
              
                public UnstructuredData getUnstructuredData(ID id) {
                  UnstructuredData unstructured = null;
                  if (id != null) {
                    unstructured = (UnstructuredData)this.unstructuredData.get(id);
                    if (unstructured == null) {
                      unstructured = 
                        (UnstructuredData)this.postprocessedUnstructuredData
                        .get(id);
                    }
              
                  }
              
                  return unstructured;
                }
              
                public StructuredData[] getStructuredData()
                {
                  Map merged = new TreeMap();
                  merged.putAll(this.structuredData);
                  merged.putAll(this.postprocessedStructuredData);
                  return (StructuredData[])merged.values().toArray(
                    structuredDataTemplateArray);
                }
              
                public StructuredData getStructuredData(ID id) {
                  StructuredData structured = null;
                  if (id != null) {
                    structured = (StructuredData)this.structuredData.get(id);
                    if (structured == null) {
                      structured = 
                        (StructuredData)this.postprocessedStructuredData
                        .get(id);
                    }
              
                  }
              
                  return structured;
                }
              
                public StructuredData getStructuredData(String label) {
                  StructuredData structured = (StructuredData)searchForLabel(
                    this.structuredData, label);
              
                  if (structured == null) {
                    structured = (StructuredData)searchForLabel(
                      this.postprocessedStructuredData, label);
                  }
                  return structured;
                }
              
                public TupleData getTupleData(String label)
                {
                  TupleData tuple = (TupleData)searchForLabel(this.tupleData, label);
              
                  if (tuple == null) {
                    tuple = (TupleData)searchForLabel(this.postprocessedTupleData, label);
                  }
                  return tuple;
                }
              
                private Data searchForLabel(Map datas, String label)
                {
                  Iterator iterator = datas.values().iterator();
              
                  while (iterator.hasNext()) {
                    Data data = (Data)iterator.next();
                    if (data.getLabel().equals(label)) {
                      return data;
                    }
                  }
              
                  return null;
                }
              
                public TupleData getTupleData(String label, Axis xAxis, Axis yAxis) {
                  Iterator it = this.tupleData.values().iterator();
                  TupleData data = null;
              
                  while (it.hasNext()) {
                    TupleData maybeData = (TupleData)it.next();
                    if ((maybeData.getLabel().equals(label)) && 
                      (maybeData.getXAxis().getAxis().equals(xAxis)) && 
                      (maybeData.getYAxis().getAxis().equals(yAxis))) {
                      data = maybeData;
                    }
              
                  }
              
                  return data;
                }
              
                public TupleData getTupleData(ID id)
                {
                  TupleData tuple = null;
                  if (id != null) {
                    tuple = (TupleData)this.tupleData.get(id);
                    if (tuple == null) {
                      tuple = (TupleData)this.postprocessedTupleData.get(id);
                    }
              
                  }
              
                  return tuple;
                }
              
                public TupleData[] getTupleData()
                {
                  Map merged = new TreeMap();
                  merged.putAll(this.tupleData);
                  merged.putAll(this.postprocessedTupleData);
                  return (TupleData[])merged.values().toArray(tupleDataTemplateArray);
                }
              
                public DomainData getData(ID id) {
                  DomainData data = null;
              
                  if (id != null) {
                    Object try1 = this.postprocessedUnstructuredData.get(id);
              
                    if (try1 != null) {
                      data = (DomainData)try1;
                    } else {
                      Object try2 = this.postprocessedStructuredData.get(id);
                      if (try2 != null) {
                        data = (DomainData)try2;
                      } else {
                        Object try3 = this.postprocessedTupleData.get(id);
                        if (try3 != null) {
                          data = (DomainData)try3;
                        } else {
                          Object try4 = this.unstructuredData.get(id);
                          if (try4 != null) {
                            data = (DomainData)try4;
                          } else {
                            Object try5 = this.structuredData.get(id);
                            if (try5 != null) {
                              data = (DomainData)try5;
                            } else {
                              Object try6 = this.tupleData.get(id);
                              if (try6 != null) {
                                data = (DomainData)try6;
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                  return data;
                }
              
                public void addAggregateData(AggregateDataImpl aggregateData) {
                  this.dataIsDirty = true;
              
                  this.unstructuredData.putAll(aggregateData.unstructuredData);
                  this.structuredData.putAll(aggregateData.structuredData);
                  this.tupleData.putAll(aggregateData.tupleData);
                }
              
                public void add(UnstructuredData data) {
                  if (data != null) {
                    this.dataIsDirty = true;
                    if (this.postprocessing)
                    {
                      this.postprocessedUnstructuredData.put(data.getID(), data);
                    }
                    else this.unstructuredData.put(data.getID(), data);
                  }
                }
              
                public void add(StructuredData data)
                {
                  if (data != null) {
                    this.dataIsDirty = true;
                    if (this.postprocessing)
                    {
                      this.postprocessedStructuredData.put(data.getID(), data);
                    }
                    else this.structuredData.put(data.getID(), data);
                  }
                }
              
                public void add(TupleData data)
                {
                  if (data != null) {
                    this.dataIsDirty = true;
                    if (this.postprocessing)
                      this.postprocessedTupleData.put(data.getID(), data);
                    else
                      this.tupleData.put(data.getID(), data);
                  }
                }
              
                protected ID generateID()
                {
                  return new AggregateIDImpl(null, "hash:" + hashCode());
                }
              
                public void switchToPostprocessing() {
                  this.postprocessing = true;
                }
              
                public void switchToParsing() {
                  this.postprocessing = false;
                }
              
                public void clear() {
                  this.unstructuredData = new TreeMap();
                  this.structuredData = new TreeMap();
                  this.tupleData = new TreeMap();
                  clearPostprocessedLayer();
                }
              
                public void clearPostprocessedLayer()
                {
                  this.postprocessedUnstructuredData = new TreeMap();
                  this.postprocessedStructuredData = new TreeMap();
                  this.postprocessedTupleData = new TreeMap();
                }
              
                protected AggregateDataImpl getCroppedData(OutputProperties properties)
                {
                  AggregateDataImpl newData = new AggregateDataImpl(getLabel());
                  for (StructuredData sd : this.structuredData.values()) {
                    newData.add(sd);
                  }
                  for (UnstructuredData ud : this.unstructuredData.values()) {
                    newData.add(ud);
                  }
                  for (TupleData td : this.tupleData.values()) {
                    newData.add(td.getCroppedTupleData(properties));
                  }
                  return newData;
                }
              }

